| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import { notFound } from "next/navigation";
- import { Suspense } from "react";
- // import clsx from "clsx";
- // import type { ProductReviewList } from "@/types/products/productDetail";
- // import { getProductReviews } from "@utils/hooks/getProductReviews";
- import { restApiFetch } from "@utils/bagisto/index";
- import {
- ProductDetailSkeleton,
- RelatedProductSkeleton,
- } from "@/components/common/skeleton/ProductSkeleton";
- import { BASE_SCHEMA_URL, PRODUCT_TYPE } from "@/utils/constants";
- import { GET_PRODUCT_BY_URL_KEY } from "@/graphql";
- import { cachedProductRequest } from "@/utils/hooks/useCache";
- import {
- ProductOption,
- SingleProductResponse,
- ProductMediaType,
- } from "@components/catalog/type";
- import { RelatedProductsSection } from "@components/catalog/product/RelatedProductsSection";
- import { HeroCarouselShimmer } from "@components/common/slider";
- import { ProductMedia } from "@/app/(public)/product/_components/ProductMedia";
- import { ProductInformation } from "@/app/(public)/product/_components/ProductInformation";
- import { ProductShortDescription } from "@/app/(public)/product/_components/ProductShortDescription";
- import { ProductDetail } from "@/app/(public)/product/_components/ProductDetail";
- import SwitchButton from "../_components/SwitchButton";
- import ShopServicePanel from "../_components/ShopServicePanel";
- import Recommend from "../_components/youmaylike/Recommend"
- import { formatFlexibleVariants } from "@/utils/variantTools";
- // export const dynamic = 'auto'
- // // 'auto' | 'force-dynamic' | 'error' | 'force-static'
- export const dynamic = "force-dynamic";
- async function getSingleProduct(urlKey: string) {
- try {
- const { data: dataById } =
- await cachedProductRequest<SingleProductResponse>(
- // urlKey, // 产品名称
- GET_PRODUCT_BY_URL_KEY, // gql查询语句
- { urlKey: urlKey },
- );
- const product = dataById?.product || null;
- return product;
- } catch (error) {
- if (error instanceof Error) {
- console.error("Error fetching product:", {
- message: error.message,
- urlKey,
- graphQLErrors: (error as unknown as Record<string, unknown>)
- .graphQLErrors,
- });
- }
- return null;
- }
- }
- //动态路由中的参数 -- params
- export default async function ProductPage({
- params,
- }: {
- params: Promise<{ urlProduct: string[] }>;
- searchParams: Promise<{ type: string }>;
- }) {
- const { urlProduct } = await params;
- const fullPath = urlProduct.join("/");
- const product = await getSingleProduct(fullPath);
- if (!product) return notFound();
- // const allReviews: ProductReviewList = await getProductReviews(
- // String(product._id),
- // );
- // 3792
- const res = await restApiFetch({
- api: `/shop/products/${3792}/reviews?page=1&per_page=10&has_images=0&sort=all`,
- method: "GET",
- });
- const allReviews = res?.body?.data;
- console.log("res----------------------",allReviews);
- const questionTotal = 73;
- // const imageUrl = getImageUrl(product?.baseImageUrl, baseUrl, NOT_IMAGE);
- // JSON-LD数据格式,便于搜索引擎识别页面信息,利于seo
- const productJsonLd = {
- "@context": BASE_SCHEMA_URL,
- "@type": PRODUCT_TYPE,
- name: product?.name,
- description: product?.description,
- sku: product?.sku,
- };
- const mediaImgs = (product?.images?.edges ?? []).map(
- (edge: { node: ProductMediaType }) => {
- return edge.node;
- },
- );
- const productOptions: ProductOption[] = product?.productOptions
- ? JSON.parse(product?.productOptions)
- : [];
- const flexibleVariants = formatFlexibleVariants(product?.flexibleVariants);
- // const reviews = Array.isArray(product?.reviews?.edges)
- // ? product?.reviews.edges.map((e) => e.node)
- // : [];
- // const VariantImages = isArray(product?.variants?.edges)
- // ? product?.variants.edges.map(
- // (edge: { node: ProductVariantNode }) => edge.node,
- // )
- // : [];
- return (
- <>
- <script //SEO
- dangerouslySetInnerHTML={{
- __html: JSON.stringify(productJsonLd),
- }}
- type="application/ld+json"
- />
- <div className="w-full">
- <Suspense fallback={<HeroCarouselShimmer />}>
- <ProductMedia mediaData={mediaImgs} />
- </Suspense>
- </div>
- <div className="">
- <Suspense fallback={<ProductDetailSkeleton />}>
- <ProductInformation
- key={product._id}
- productId={product._id}
- name={product?.name || ""}
- productOptions={productOptions}
- flexibleVariants={flexibleVariants}
- isSaleable={product.isSaleable}
- />
- <ShopServicePanel />
- <ProductShortDescription
- shortDescription={product.shortDescription || ""}
- />
- <SwitchButton
- productId={"3792"} //|| String(product._id)
- reviewList={allReviews}
- reviewTotal={allReviews.length}
- questionTotal={questionTotal}
- questionList={["aaa"]}
- />
- <ProductDetail detail={product.description || ""} />
- {/* <ProductReviewSection reviews={allReviews} productId={String(product._id)} /> */}
- </Suspense>
- <Recommend/>
- </div>
-
- <Suspense fallback={<RelatedProductSkeleton />}>
- <RelatedProductsSection fullPath={fullPath} />
- </Suspense>
- </>
- );
- }
|